
package com.wise.api.utils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.apache.commons.lang.ArrayUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.entity.GzipDecompressingEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * <p>
 * 版权所有： 天津金蝶软件有限公司
 * <p>
 * Title: HttpClientHelper
 * <p>
 * Description: http请求帮助类
 * 
 * @author yacong_liu Email:2682505646@qq.com
 * @date 2018年12月13日
 */
public class HttpClientHelper {
	private static Logger logger = LoggerFactory.getLogger(HttpClientHelper.class);

	private static HttpClientHelper instance = null;

	private static Lock lock = new ReentrantLock();

	private CloseableHttpClient httpClient = null;

	private final static int MAX_TOTEL = 1000;

	private final static int MAX_CONNECTION_PER_ROUTE = 100;

	private HttpClientHelper() {
		instance = this;
	}

	public static HttpClientHelper getHttpClient() {
		if (instance == null) {
			lock.lock();
			try {
				if (instance == null) {
					instance = new HttpClientHelper();
					instance.init();
				}
			} finally {
				lock.unlock();
			}
		}

		return instance;
	}

	private void init() {
		PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
		cm.setMaxTotal(MAX_TOTEL);
		cm.setDefaultMaxPerRoute(MAX_CONNECTION_PER_ROUTE);
		httpClient = HttpClientBuilder.create().setConnectionManager(cm).build();
	}

	public String execute(HttpRequestBase request, String charset) throws UnsupportedEncodingException {
		byte[] returnByte = executeAndReturnByte(request);
		if (ArrayUtils.isEmpty(returnByte) ) {
			return null;
			
		}

		return new String(returnByte, charset);
	}

	public byte[] executeAndReturnByte(HttpRequestBase request) {
		byte[] rtn = new byte[0];

		if (request == null) {
			return rtn;
		}

		try {
			lock.lock();
			if (httpClient == null) {
				init();
			}
		} finally {
			lock.unlock();
		}

		if (httpClient == null) {
			logger.error("{}\nreturn error {}", request.getURI().toString(), "httpclient连接获取异常！");
			return rtn;
		}

		HttpEntity entity = null;
		CloseableHttpResponse response = null;
		try {
			response = httpClient.execute(request);
			entity = response.getEntity();
			int statusCode = response.getStatusLine().getStatusCode();
			if (statusCode == 200) {
				logger.info("{}\nreturn correctly httpstatus code:{}", request.getURI().toString(), statusCode);

				String encoding = ("" + response.getFirstHeader("Content-Encoding")).toLowerCase();
				if (encoding.indexOf("gzip") > 0) {
					entity = new GzipDecompressingEntity(entity);
				}

				rtn = EntityUtils.toByteArray(entity);
			} else if (statusCode == 400) {
				rtn = EntityUtils.toByteArray(entity);
				logger.error("{}\nreturn error httpstatus code:{}", request.getURI().toString(), statusCode);
			} else {
				logger.error("{}\nreturn error httpstatus code:{}", request.getURI().toString(), statusCode);
			}

		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		} finally {
			EntityUtils.consumeQuietly(entity);
			if (response != null) {
				try {
					response.close();
				} catch (IOException e) {
					logger.error("httpclient连接释放异常！", e);
				}
			}
		}

		return rtn;

	}

}
